﻿using System;
using System.Collections;
using System.Reflection;
using Castle.Core;
using Castle.MonoRail.Framework;
using Castle.MonoRail.Framework.Descriptors;
using Castle.MonoRail.Framework.Services.Utils;
using Castle.MonoRail.WindsorExtension;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;


namespace StateTheater
{
    public class MonoRailContainer : WindsorContainer
    {
        public MonoRailContainer(IList controllerAssemblies) : base(new XmlInterpreter())
        {
            this.AddFacility("rails", new MonoRailFacility());
            foreach (string controllerAssemblyName in controllerAssemblies)
            {
                Assembly a = Assembly.Load(controllerAssemblyName);
                RegisterControllers(a);
                RegisterViewComponents(a);
            }
        }

        private void RegisterViewComponents(Assembly componentAssembly)
        {
            foreach (Type type in componentAssembly.GetExportedTypes())
            {
                if (!type.IsPublic || type.IsAbstract || type.IsInterface || type.IsValueType)
                {
                    continue;
                }

				// Only install types derived from ViewComponent and not already installed (ie. through .config) 
                if (typeof(ViewComponent).IsAssignableFrom(type) && !Kernel.HasComponent(type))
                {
                    string key = string.Format("{0}", type.Name);
					AddComponentLifeStyle(key, type, LifestyleType.Transient);
                }
            }
        }

        private void RegisterControllers(Assembly controllerAssembly)
        {
            foreach (Type type in controllerAssembly.GetExportedTypes())
            {
                if (!type.IsPublic || type.IsAbstract || type.IsInterface || type.IsValueType)
                {
                    continue;
                }

                // Only install types derived from Controller and not already installed (ie. through .config) 
                if (typeof(Controller).IsAssignableFrom(type) && !Kernel.HasComponent(type))
                {
                    ControllerDescriptor descriptor = ControllerInspectionUtil.Inspect(type);

                    // The key is areaname.controllername.controller
                    string key = string.Format("{0}{1}{2}.controller", descriptor.Area, String.IsNullOrEmpty(descriptor.Area) ? String.Empty : ".", descriptor.Name);
					AddComponentLifeStyle(key, type, LifestyleType.Transient);

                }
            }
        }
    }
}